package com.yxw.yxnet_cd_center.customer_service.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxw.yxnet_cd_center.common.constant.CommonConstant;
import com.yxw.yxnet_cd_center.common.dto.PageVO;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import com.yxw.yxnet_cd_center.common.utils.BaseDateTime;
import com.yxw.yxnet_cd_center.customer_service.dto.*;
import com.yxw.yxnet_cd_center.customer_service.entity.*;
import com.yxw.yxnet_cd_center.customer_service.mapper.*;
import com.yxw.yxnet_cd_center.customer_service.service.WorkflowService;
import com.yxw.yxnet_cd_center.customer_service.utils.PageUtils;
import com.yxw.yxnet_cd_center.customer_service.utils.StringUtil;
import com.yxw.yxnet_cd_center.customer_service.utils.UserUtil;
import com.yxw.yxnet_cd_center.customer_service.vo.DictionaryVo;
import com.yxw.yxnet_cd_center.customer_service.vo.YxCsWorkflowForUserVo;
import com.yxw.yxnet_cd_center.customer_service.vo.YxCsWorkflowVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 登录管理
 *
 * @author liuxin
 * @date 2023.09.12
 */
@Service
public class WorkflowServiceImpl extends ServiceImpl<WorkflowMapper, YxCsWorkflowEntity> implements WorkflowService {

    @Autowired
    private WorkflowMapper workflowMapper;

    @Autowired
    private UserUtil userUtil;

    @Autowired
    private DictMapper dictMapper;

    @Autowired
    private YxCsFlockUserMapper yxCsFlockUserMapper;

    @Autowired
    private YxCsFlowRuleMapper yxCsFlowRuleMapper;

    @Autowired
    private YxScFlowRuleUserMapper yxScFlowRuleUserMapper;


    /**
     * 查询工作流转接记录
     *
     * @param dto
     * @return
     */
    @Override
    public PageVO<YxCsWorkflowVo> getWorkflowList(WorkflowQueryDTO dto) {
        Page<YxCsWorkflowEntity> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        LambdaQueryWrapper<YxCsWorkflowEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(dto.getGroupName()), YxCsWorkflowEntity::getGroupName, StringUtil.trim(dto.getGroupName())).
                like(StringUtils.isNotBlank(dto.getUserName()), YxCsWorkflowEntity::getCustomName,StringUtil.trim(dto.getUserName())).
                eq(null != dto.getWorkflowType(), YxCsWorkflowEntity::getEndFlag, dto.getWorkflowType()).
                ge(StringUtils.isNotBlank(dto.getCreateTimeStart()), YxCsWorkflowEntity::getCreateTime, BaseDateTime.getDate(dto.getCreateTimeStart())).
                le(StringUtils.isNotBlank(dto.getCreateTimeEnd()), YxCsWorkflowEntity::getCreateTime, BaseDateTime.getDate(dto.getCreateTimeEnd())).
                orderByDesc(true, YxCsWorkflowEntity::getCreateTime);
        page = baseMapper.selectPage(page, queryWrapper);
        List<YxCsWorkflowEntity> entityList = page.getRecords();
        List<YxCsWorkflowVo> listVoList = new ArrayList<>();
        if (null != entityList && !entityList.isEmpty()) {
            listVoList = BeanUtil.copyToList(entityList, YxCsWorkflowVo.class);
        }
        return PageUtils.get(page, listVoList);
    }

    /**
     * 分流管理-设置分流规则
     *
     * @param dto
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addWorkflowRule(YxCsFlowRuleEntity entity, FlowRuleAddDTO dto) {
        //校验规则是否全部分配完毕
        validataRule(dto);
        //删除原有分流规则和人员
        LambdaQueryWrapper<YxCsFlowRuleEntity> ruleWrapper = new LambdaQueryWrapper<>();
        ruleWrapper.eq(true,YxCsFlowRuleEntity::getFlockId,entity.getFlockId());
        List<YxCsFlowRuleEntity> yxCsFlowRuleEntities = yxCsFlowRuleMapper.selectList(ruleWrapper);
        if(null!=yxCsFlowRuleEntities && !yxCsFlowRuleEntities.isEmpty()){
            for (YxCsFlowRuleEntity flowRule: yxCsFlowRuleEntities) {
                //删除规则
                yxCsFlowRuleMapper.deleteById(flowRule.getId());
                //删除规则人员
                LambdaUpdateWrapper<YxScFlowRuleUserEntity> ruleUserWrapper = new LambdaUpdateWrapper<>();
                ruleUserWrapper.eq(true,YxScFlowRuleUserEntity::getFlowRuleId,flowRule.getId());
                yxScFlowRuleUserMapper.delete(ruleUserWrapper) ;
            }
        }
        List<FlowRuleFitDTO> fitList = dto.getFitList();
        Long userId = userUtil.getLoginUserId();
        String userName = userUtil.getLoginName();
        //根据渠道+端口+服务类型+规则
        for (FlowRuleFitDTO fit : fitList) {
            //查询分流规则类型
            entity.setRuleType(fit.getRuleType());
            entity.setCreateId(userId);
            entity.setCreateName(userName);
            entity.setCreateTime(new Date());
            entity.setStatus(CommonConstant.ZERO);
            //规则
            DictionaryVo ruleData = dictMapper.getDictDataById(fit.getRuleType());
            if (null != ruleData) {
                entity.setRuleTypeCode(ruleData.getCode());
                entity.setRuleTypeName(ruleData.getName());
            }
            workflowMapper.addWorkflowRule(entity);
            //一级分类规则查询
            SysDictDataEntity firstRuleType = dictMapper.selectById(dto.getFirstRuleType());
            if("base_rule_type".equals(firstRuleType.getDictValue())){
                //新增规则人员信息
                LambdaQueryWrapper<YxCsFlockUserEntity> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(true,YxCsFlockUserEntity::getFlockId,entity.getFlockId());
                List<YxCsFlockUserEntity> yxCsFlockUserEntities = yxCsFlockUserMapper.selectList(queryWrapper);
                if(null!=yxCsFlockUserEntities && !yxCsFlockUserEntities.isEmpty()){
                    List<Long> userIdList = yxCsFlockUserEntities.stream().map(user -> user.getUserId()).collect(Collectors.toList());
                    workflowMapper.addFlowRuleUser(entity.getId(),userIdList);
                }
            }else{
                workflowMapper.addFlowRuleUser(entity.getId(), fit.getUserIdList());
            }
        }
    }
    /**
     * 工作流管理-工作流记录删除
     *
     * @param id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteWorkflowById(Long id) {
        baseMapper.deleteById(id);
    }


    /**
     * 人员分流规则查询
     */
    @Override
    public PageVO<YxCsWorkflowForUserVo> getWorkflowListForUser(WorkflowForUserQueryDTO dto) {
        // 去除参数字段的空格
        String userName = dto.getUserName();
        String portCode = dto.getPortCode();
        String channelCode = dto.getChannelCode();
        String serviceTypeCode = dto.getServiceTypeCode();
        String ruleTypeCode = dto.getRuleTypeCode();
        String flockName = dto.getFlockName();
        String groupName = dto.getGroupName();
        String flowName = dto.getFlowName();

        Page<YxCsWorkflowEntity> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        page.setCurrent(dto.getCurrPage());  // 设置当前页
        page.setSize(dto.getPageSize());  // 设置页面大小
        List<YxCsWorkflowForUserVo> list = workflowMapper.getWorkflowListForUser(userName, portCode, channelCode, serviceTypeCode, ruleTypeCode, flockName, groupName, flowName);
        int startIndex = (dto.getCurrPage() - 1) * dto.getPageSize();
        int endIndex = Math.min(startIndex + dto.getPageSize(), list.size());
        List<YxCsWorkflowForUserVo> result = list.subList(startIndex, endIndex);
        page.setTotal(list.size());
        return PageUtils.get(page, result);
    }


    //-----------------------------------------------------------------------------------------------------------------------

    /**
     * 1：校验规则是不是全部分配
     * 2：校验规则相同时候是否存在人员
     * 3：基础分流不校验
     * @param dto
     */
    private void validataRule(FlowRuleAddDTO dto) {
        //基础分流校验是否存在其他分流规则，存在就不允许再分配
        SysDictDataEntity firstRuleType = dictMapper.selectById(dto.getFirstRuleType());
        if("base_rule_type".equals(firstRuleType.getDictValue())){
            return;
        }else{
            //校验是否都选择了人员
            List<FlowRuleFitDTO> fitList = dto.getFitList();
            if(null==fitList || fitList.isEmpty()){
                throw new BaseException("请选择规则");
            }
            for (int i = 0; i <fitList.size() ; i++) {
                FlowRuleFitDTO fitDTO = fitList.get(i);
                List<Long> userIdList = fitDTO.getUserIdList();
                if(null==userIdList || userIdList.isEmpty()){
                    throw new BaseException("存在规则未选择人员");
                }
            }
        }
        StringBuffer sbf=new StringBuffer();
        List<FlowRuleFitDTO> fitList = dto.getFitList();
        //查询四大规则对应的规则类型
        DictQueryDTO  dictQuery=new DictQueryDTO();
        dictQuery.setStatus(CommonConstant.ZERO);
        dictQuery.setDictType(firstRuleType.getDictValue());
        List<DictionaryVo> ruleTypeList = dictMapper.getDictDataByType(dictQuery);
        if(null==ruleTypeList || ruleTypeList.isEmpty()){
            throw new BaseException("规则查询异常");
        }
        //规则是否分配完毕
        List<Long> ruleList = fitList.stream().map(rule -> rule.getRuleType()).collect(Collectors.toList());
        for (int i = 0; i < ruleTypeList.size(); i++) {
            DictionaryVo dictionaryVo = ruleTypeList.get(i);
            Long ruleId = dictionaryVo.getId();
            String name = dictionaryVo.getName();
            if(!ruleList.contains(ruleId)){
                sbf.append(firstRuleType.getDictLabel()+"对应的规则【"+name+"】还未分配<br>");
            }
        }
        //同规则下面不能存在相同的人，根据规则和人组合然后再判断是否存在重复的数据
//        List<String> ruleUserList=new ArrayList<>();
//        for (int i = 0; i <fitList.size(); i++) {
//            FlowRuleFitDTO flowRuleFitDTO = fitList.get(i);
//            Long ruleType = flowRuleFitDTO.getRuleType();
//            List<Long> userIdList = flowRuleFitDTO.getUserIdList();
//            for (int j = 0; j < userIdList.size(); j++) {
//                ruleUserList.add(ruleType+"_"+userIdList.get(j));
//            }
//        }
//        List<String> userRepeatList = ruleUserList.stream() .filter( t1 -> ruleUserList.stream().filter(t2 -> t1.equals(t2)).count() > 1).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
//        for (String userRepeat:userRepeatList) {
//            Long ruleType= Long.valueOf(userRepeat.split("_")[0]);
//            String userName=ruleTypeList.stream().filter(rule -> rule.getId().compareTo(ruleType)==0).collect(Collectors.toList()).get(0).getName();
//            sbf.append("规则【"+userName+"】分配了相同人员,请调整人员<br>");
//        }
        if( StringUtils.isNotBlank(sbf.toString())){
           throw new BaseException(sbf.toString());
        }
    }
}
